<?php

namespace App\Models;


use App\Service\Base\Model;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class News extends Model
{

    // 用户管理
    protected $table = 'news';

    // 缓存字段，用于搜索绑定的字段
    protected $cacheFields = ['id', 'uid', 'verify', 'is_top', 'is_push',];

    // {"id":"自编号","title":"标题","uid":"用户id","cover":"图片","keyword":"关键字","description":"描述","read_no":"浏览数","virtual_no":"虚拟浏览数","praise_no":"点赞数","collect_no":"收藏数","relay_no":"转发次数","comment_no":"评论数","images":"图片集合","verify":"是否审核（1-是，-1删除）","ip":"ip地址","ip_address":"ip的实际地址","is_top":"是否置顶（1-是）","push_time":"发布时间","ctime":"创建时间","mtime":"修改时间"}

    // array ( 'id' => '$this->getData("id", null, "trim")', 'title' => '$this->getData("title", null, "trim")', 'uid' => '$this->getData("uid", null, "trim")', 'cover' => '$this->getData("cover", null, "trim")', 'keyword' => '$this->getData("keyword", null, "trim")', 'description' => '$this->getData("description", null, "trim")', 'read_no' => '$this->getData("read_no", null, "trim")', 'virtual_no' => '$this->getData("virtual_no", null, "trim")', 'praise_no' => '$this->getData("praise_no", null, "trim")', 'collect_no' => '$this->getData("collect_no", null, "trim")', 'relay_no' => '$this->getData("relay_no", null, "trim")', 'comment_no' => '$this->getData("comment_no", null, "trim")', 'images' => '$this->getData("images", null, "trim")', 'verify' => '$this->getData("verify", null, "trim")', 'ip' => '$this->getData("ip", null, "trim")', 'ip_address' => '$this->getData("ip_address", null, "trim")', 'is_top' => '$this->getData("is_top", null, "trim")', 'push_time' => '$this->getData("push_time", null, "trim")', 'ctime' => '$this->getData("ctime", null, "trim")', 'mtime' => '$this->getData("mtime", null, "trim")', )


    //$id = $this->getData("id", null, 'trim'); $title = $this->getData("title", null, 'trim'); $uid = $this->getData("uid", null, 'trim'); $cover = $this->getData("cover", null, 'trim'); $keyword = $this->getData("keyword", null, 'trim'); $description = $this->getData("description", null, 'trim'); $read_no = $this->getData("read_no", null, 'trim'); $virtual_no = $this->getData("virtual_no", null, 'trim'); $praise_no = $this->getData("praise_no", null, 'trim'); $collect_no = $this->getData("collect_no", null, 'trim'); $relay_no = $this->getData("relay_no", null, 'trim'); $comment_no = $this->getData("comment_no", null, 'trim'); $images = $this->getData("images", null, 'trim'); $verify = $this->getData("verify", null, 'trim'); $ip = $this->getData("ip", null, 'trim'); $ip_address = $this->getData("ip_address", null, 'trim'); $is_top = $this->getData("is_top", null, 'trim'); $push_time = $this->getData("push_time", null, 'trim'); $ctime = $this->getData("ctime", null, 'trim'); $mtime = $this->getData("mtime", null, 'trim');

    // 添加
    public function oneAdd($data = [])
    {
        // 验证信息
        $rules  = $this->fieldRule();
        $result = $this->validator($data, $rules, ['id' => '修改的用户编号']);
        if($result === false){
            return false;
        }

        // 参数
        $news_id = $data['id'] ?? 0;
        $uid     = $data['uid'] ?? 0;
        if(empty($uid)){
            return $this->return_false('请指定发帖用户!');
        }
        /*if(empty($data['content'])){
            return $this->return_false('请填写内容!');
        }*/

        // 模型
        //$descDb    = new NewsDesc();
        $userDb = new User();

        // 如果是修改 查询内容信息
        $info     = [];
        $descInfo = [];
        if($news_id){
            $info = $this->isCache(true)->oneFind(["id" => $data['id']]);
            $info = is_object($info) ? $info->toArray() : $info;
            if(empty($info)){
                return $this->return_false('你要修改的内容不存在!');
            }
            if($info['verify'] == -1){
                return $this->return_false('你要修改的内容已经删除!');
            }

            // 以前的用户
            $old_uid = $info['uid'];

            // 发帖数量
            $userDataAdd = ['news_no' => DB::raw('news_no'.'+1'), 'mtime' => LARAVEL_TIME];
            $userDataDsc = ['news_no' => DB::raw('news_no'.'-1'), 'mtime' => LARAVEL_TIME];

            // 是否改变
            $changeUser = $old_uid != $uid;

            // 数据
            $articleData = $this->filterField($data);
            //$descData    = $descDb->filterField($data);
            /*if($descData){
                $descInfo = $descDb->isCache(true)->oneFind(['news_id' => $news_id]);
            }*/
        } else{
            $changeUser = true;
            // 整理数据
            //   阿特的用户 与 转发的数据
            $userDataAdd = ['news_no' => DB::raw('news_no'.'+1'), 'mtime' => LARAVEL_TIME];
            $userDataDsc = [];

            // 模型数据
            $articleData = $this->filterField($data);
            //$descData    = $descDb->filterField($data);
            $this->fill($articleData);
            //$descDb->fill($descData);
        }


        unset($data['host'], $data['guest'], $data['voice_text']);
        // 保存数据
        DB::beginTransaction();
        try{
            /*// 如果有置顶
            if($is_top){
                // 取消其他置顶
                $result = $this->where(['is_top' => $is_top])->update(['is_top' => 0]);
            }*/

            // 修改
            if($news_id){
                $newId = $data['id'];
                unset($data['id'], $data['channel']); // $descData['id'],
                // 主表
                if($articleData){
                    $result = $this->where('id', $newId)->update($articleData);
                }
                // 附表
                /*if($descData){
                    $result = $descDb->where('news_id', $newId)->update($descData);
                }*/

            } else{
                // 添加
                $this->save();
                $newId = $this->id;
                // 详情表
                //$descDb->news_id = $newId;
                // 整理
                //$result = $descDb->save();
            }


            // 更新用户发帖数量
            if($changeUser){
                /*if($userDataAdd){
                    $userDb->where('id', $uid)->update($userDataAdd);
                }
                if($userDataDsc){
                    $userDb->where('id', $old_uid)->update($userDataDsc);
                }*/
            }

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->return_false($e->getMessage());
        }


        // 缓存操作
        $this->deleteCacheShow($data, $info);
        $userDb->deleteCacheShow(['id' => $uid]);

        /*$descDb->deleteCacheShow($data, $descInfo);
        if(!empty($old_uid)){
            $userDb->deleteCacheShow(['id' => $old_uid]);
        }*/

        return $this->id;
    }

    // 修改
    // TODO 栏目话题可以是多个的数组，也可以是单个字符串（不能是多个组合的字符串）
    public function oneEdit($where, $data)
    {
        // 查询
        $info = $this->isCache(true)->oneFind($where);  // ->recycle()
        if(empty($info)){
            return $this->return_false('你要修改的数据不存在！！');
        }

        $info    = is_object($info) ? $info->toArray() : $info;
        $news_id = $info['id'];
        // 模型
        //$descDb = new NewsDesc();


        // 以前的数据 与 现在的数据
        $old_uid = $info['uid'];
        $uid     = $data['uid'] ?? null;

        // 数据
        $articleData = $this->filterField($data);
        /*$descData    = $descDb->filterField($data);
        $descInfo    = [];
        if($descData){
            $descInfo = $descDb->isCache(true)->oneFind(['news_id' => $news_id]);
        }*/

        // 属性表改变
        $isChange = (!is_null($uid)) && ($uid != $old_uid);

        // 文章话题数据
        // 以前的数据 与 现在的数据 （话题是多个）
        $userMain     = new User();
        $old_cate_ids = $info['cate_ids'] ?? [];
        $cate_ids     = $data['cate_ids'] ?? [];
        $addCateIds   = $delCateIds = false;

        // 组合用于删除的缓存
        $data['cate_id'] = array_merge($old_cate_ids, $cate_ids);

        // 栏目的变化整理
        $addCate = [];
        $delCate = [];
        if($cate_ids && ($cate_ids != $old_cate_ids)){
            $addCateIds = array_diff($cate_ids, $old_cate_ids);  // 这些话题文章数量+1
            $delCateIds = array_diff($old_cate_ids, $cate_ids);  // 这些话题文章数量-1
            if($addCateIds){
                foreach($addCateIds as $_cateId){
                    if($_cateId){
                        $addCate[] = ['news_id' => $news_id, 'ctime' => LARAVEL_TIME, 'cate_id' => $_cateId,];
                    }
                }
            }
            if($delCateIds){
                foreach($delCateIds as $_cateId){
                    $delCate[] = ['news_id' => $news_id, 'cate_id' => $_cateId,];
                }
            }
        }


        // 文章数量
        $addNumData = ['news_no' => DB::raw("news_no+1"),];
        $decNumData = ['news_no' => DB::raw("news_no-1"),];

        // 保存数据
        DB::beginTransaction();
        try{
            /*// 如果有置顶
            if($is_top){
                // 取消其他置顶
                $result = $this->where(['is_top' => $is_top])->update(['is_top' => 0]);
            }*/

            // 主表
            if($articleData){
                $result = $this->where('id', $news_id)->update($articleData);
            }
            // 附表
            /*if($descData){
                $result = $descDb->where('news_id', $news_id)->update($descData);
            }*/


            /*// 添加文章栏目表
            if($addCate){
                $result = $cateDb->insert($addCate);
            }
            // 删除文章栏目表
            if($delCateIds){
                $result = $cateDb->where('news_id', $news_id)->whereIn('cate_id', $delCateIds)->delete();
            }
            // 栏目文章数量
            if($addCateIds){
                //$result = $cateMain->whereIn('id', $addCateIds)->update($addNumData);
            }
            if($delCateIds){
                //$result = $cateMain->whereIn('id', $delCateIds)->update($decNumData);
            }*/

            // 用户文章数量
            if($old_uid != $uid){
                //$result = $userMain->where('id', $uid)->update($addNumData);
                //$result = $userMain->where('id', $old_uid)->update($decNumData);
            }

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->return_false($e->getMessage());
        }

        // 缓存操作
        $this->deleteCacheShow($info, $data);

        /*$descDb->deleteCacheShow($descInfo);
        $cateMain->deleteCacheShow(['id' => $delCateIds]);
        $cateMain->deleteCacheShow(['id' => $addCateIds]);
        if($old_uid != $uid){
            $userMain->deleteCacheShow(['id' => $uid]);
            $userMain->deleteCacheShow(['id' => $old_uid]);
        }*/

        return $result;
    }

    // 详情
    public function oneFind($where, $order = "id DESC")
    {
        // 获取缓存
        $is_cache = $this->is_cache || $this->bang;
        $args     = compact('where', 'order');
        $info     = null;
        if($is_cache){
            $cacheName = $this->cacheKey('show', $args);
            $info      = $this->cacheClass()->getCache($cacheName);
            // 检查是否已经绑定
            if($info){
                $this->checkBangShow($info, $cacheName);
            }
        }
        // 查询
        if(empty($info)){
            //  查询
            $query = $this->where($where);
            if(is_array($order)){
            } else{
                $order = explode(" ", $order);
                $query = $query->orderby($order[0], $order[1]);
            }
            $info = $query->first(); // ->recycle()
            if(empty($info)){
                return $this->return_false('数据不存在！！');
            }

            // 查询属性
            /*$desc = (new NewsDesc())->where('news_id', $info->id)->first();
            $desc = $desc ? $desc->toArray() : [];
            unset($desc['id']);*/


            // 组合
            $info = $info->toArray();
            //$info = array_merge($desc, $info);

            // 保存为缓存
            if($is_cache){
                $this->addCacheShow($info, $cacheName, $info);
            }
        }

        // 后台编辑
        $info['user'] = [];
        if($info['uid']){
            $info['user'] = (new User())->isCache(true)->getOneById($info['uid']);
        }

        return $info;
    }

    // 获取多条数据+翻页
    public function listPage($where = [], $page = 1, $rows = 10, $order = "id DESC")
    {
        // 获取缓存
        $bang     = $this->bang;
        $is_cache = $this->is_cache || $bang;
        $args     = compact('where', 'page', 'rows', 'order');
        if($is_cache){
            $cacheName = $this->cacheKey('lists', $args);
            $cacheData = $this->cacheClass()->getCache($cacheName);
            if(!empty($cacheData)){
                // 检查是否已经绑定
                if(($cacheData) && (!empty($cacheData['list']))){
                    $this->checkBangList($cacheData['list'], $cacheName);
                }

                return $cacheData;
            }
        }

        // 字段
        $fields    = $this->inFields;
        $outFields = $this->outFields;
        if(empty($fields)){
            $fields = $this->getTableField(true);
        }
        if(is_string($fields)){
            $fields = explode(",", $fields);
        }
        if($outFields){
            if(is_string($outFields)){
                $outFields = explode(",", $outFields);
            }
            $fields = array_diff($fields, $outFields);
        }

        $all_size = $rows + 1;
        if(empty($where)){
            $query = $this->select($fields)->forPage($page, $rows);
            $count = $this->count();
        } else{
            if(is_array($where)){
                // 查询  ->recycle()  ->orderby($order)
                $query = $this->where($where)->select($fields)->forPage($page, $rows);
                $count = $this->where($where)->count();
            } elseif(is_string($where)){
                // 查询  ->recycle()  ->orderby($order)
                $query = $this->whereRaw($where)->select($fields)->forPage($page, $rows);
                $count = $this->whereRaw($where)->count();
            } /*else{
                // 查询  ->recycle()  ->orderby($order)
                $query = $where->select($fields)->forPage($page, $rows);
                $count = $where->count();
            }*/
        }


        if(is_array($order)){
            $query = $query->orderBy($order[0], $order[1]);
        } else{
            $query = $query->orderByRaw($order);
        }

        // 查找过滤
        $is_next = 0;
        $lists   = $query->get()->toArray();
        // 查看是否需要翻页
        if($page * $rows < $count){
            $is_next = 1;
        }

        // 过滤json
        $jsonField = isset($this->jsonField) ?: '';
        if(!empty($jsonField)){
            $jsonField = is_string($jsonField) ? explode(',', $jsonField) : $jsonField;
            foreach($lists as $_list){
                foreach($jsonField as $_field){
                    $_list->$_field = json_decode($_list->$_field, 1);
                }
            }
        }

        // 返回编辑作者
        $uids = array_unique(array_column($lists, 'uid'));
        if($uids){
            $userDb = new User();
            $users  = $userDb->isCache(true)->getListInIds($uids);
            foreach($lists as &$item){
                $_uid = $item['uid'];
                // 整理
                $item['user'] = $users[$_uid] ?? [];
                // 头像
                if($item['user']){
                    $item['user']['head_img'] = $this->getFullUrl($item['user']['head_img']);
                }
            }
        }


        $result = ['total' => $count, 'page' => $page, 'rows' => $rows, 'is_next' => $is_next, 'list' => $lists,];
        // 保存为缓存
        if($is_cache){
            $this->addCacheList($lists, $cacheName, $result, 'list');
        }

        return $result;
    }


    // 删除文章
    public function softDelete($where)
    {
        $lists = $this->isCache(true)->getList($where);  //->recycle()
        if(empty($lists)){
            return $this->return_false('你要删除的数据不存在！！');
        }

        $_ids = array_column($lists, 'id');
        // 查找有关的用户
        $userNum = [];
        foreach($lists as $item){
            $_uid = $item['uid'];
            // 重新整理
            $userNum[$item['id']][$_uid] = ($userNum[$item['id']][$_uid] ?? 0) + 1;
        }
        // 查找阿特的用户
        $_channels = array_column($lists, 'channel', 'id');


        $userDb = new User();
        DB::beginTransaction();
        try{
            // 删除文章附件，属性，日志，评论
            $this->whereIn('id', $_ids)->update(['verify' => -1]);

            // 减少栏目
            /*if($cateNum){
                foreach($cateNum as $kk => $nn){
                    $nsDb->where('id', $kk)->update(['news_no' => DB::raw("news_no-".$nn)]);
                }
            }*/

            // 减少用户文章数量
            /*if($userNum){
                foreach($userNum as $_newsId => $nItem){
                    $_channel = $_channels[$_newsId] ?? '';
                    if(empty($_channel)){
                        continue;
                    }
                    foreach($nItem as $_id => $_num){
                        if(empty($_num)){
                            continue;
                        }
                        $userData = [
                            $_channel.'_no' => DB::raw($_channel."_no-".$_num),
                            'publish_no'    => DB::raw("publish_no-".$_num),
                        ];
                        $userDb->where('id', $_id)->where($_channel.'_no', '>=', $_num)->update($userData);
                    }
                }
            }*/

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->return_false($e->getMessage());
        }

        // 缓存操作
        /*if($cateNum){
            foreach($cateNum as $kk => $nn){
                $nsDb->reSaveCache($kk, ['news_no' => "-".$nn]);
            }
        }*/
        $this->deleteCacheList($lists);
        $this->deleteCacheShow(['id' => $_ids, 'verify' => -1]);
        $userDb->deleteCacheShow(['id' => array_column($lists, 'uid')]);

        /*if($userNum){
            foreach($userNum as $_newsId => $nItem){
                $_channel = $_channels[$_newsId] ?? '';
                if(empty($_channel)){
                    continue;
                }
                foreach($nItem as $_id => $_num){
                    if(empty($_num)){
                        continue;
                    }
                    $userCache = [$_channel.'_no' => "-".$_num, 'publish_no' => "-".$_num,];
                    //$userDb->reSaveCache($_id, $userCache);
                    $userDb->deleteCacheShow(['id' => $_id]);
                }
            }
        }*/


        return true;
    }

    // 文件地址
    protected function getFullUrl($url)
    {
        if(!$url) return '';
        if(substr($url, 0, 4) != 'http'){
            $domain = Config::get('site.cdnHost');
            $domain = substr($domain, -1) == '/' ? substr($domain, 0, -1) : $domain;
            $url    = $domain.$url;
        }

        return $url;
    }

    // 定义验证操作
    public function rules()
    {

        $add = [
        ];

        $edit = [
        ];

        $info = [
        ];


        $rule = [
            // 详情
            // 'content'     => 'required',

            'title'       => 'required',
            'uid'         => 'required',
            'description' => 'required',
            'verify'      => ['in:-1,0,1'],
            //'cover'       => 'required',
            //'keyword'     => 'required',
            //'images'      => 'required',


            //'verify'      => ['in:-1,0,1'],
            //'status'      => ['in:-1,0,1,2'],
        ];


        $msg = [
            'id'          => '自编号',
            'title'       => '标题',
            'uid'         => '用户id',
            'cover'       => '图片',
            'keyword'     => '关键字',
            'description' => '描述',
            'read_no'     => '浏览数',
            'virtual_no'  => '虚拟浏览数',
            'praise_no'   => '点赞数',
            'collect_no'  => '收藏数',
            'relay_no'    => '转发次数',
            'comment_no'  => '评论数',
            'images'      => '图片集合',
            'verify'      => '是否审核（1-是，-1删除）',
            'ip'          => 'ip地址',
            'ip_address'  => 'ip的实际地址',
            'is_top'      => '是否置顶（1-是）',
            'push_time'   => '发布时间',
            'ctime'       => '创建时间',
            'mtime'       => '修改时间',
        ];

        return ['rule' => $rule, 'msg' => $msg, 'add' => $add];
    }

}
